namespace SilverSea.Sockets
{
    using System;
    using System.Collections;
    using System.Diagnostics;
    using System.IO;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading;

    public class SocketServer
    {
        private ArrayList arrayList_0;
        private AsyncCallback asyncCallback_0;
        private bool bool_0;
        private int int_0;
        private int int_1;
        private Socket socket_0;
        private string string_0;

        public event ClientConnectedEventHandler ClientConnectedEvent;

        public event DataReceivedInByteArrayEventHandler DataReceivedInByteArrayEvent;

        public event DataReceivedInStringEventHandler DataReceivedInStringEvent;

        public event SocketErrorEventHandler SocketErrorEvent;

        public SocketServer()
        {
            this.arrayList_0 = ArrayList.Synchronized(new ArrayList());
            this.string_0 = "127.0.0.1";
            this.int_1 = 0xc350;
        }

        public SocketServer(string serverIP, int serverPort)
        {
            this.arrayList_0 = ArrayList.Synchronized(new ArrayList());
            this.string_0 = "127.0.0.1";
            this.int_1 = 0xc350;
            this.string_0 = serverIP;
            this.int_1 = serverPort;
        }

        private void method_0(IAsyncResult iasyncResult_0)
        {
            try
            {
                Socket socket = this.socket_0.EndAccept(iasyncResult_0);
                this.arrayList_0.Add(socket);
                Interlocked.Increment(ref this.int_0);
                this.method_1(socket, this.int_0);
                if (this.ClientConnectedEvent != null)
                {
                    this.ClientConnectedEvent(this.int_0, socket.RemoteEndPoint.ToString());
                }
                this.socket_0.BeginAccept(new AsyncCallback(this.method_0), null);
            }
            catch (ObjectDisposedException)
            {
                Debugger.Log(0, "1", "\n OnClientConnection: Socket has been closed\n");
            }
            catch (SocketException exception)
            {
                if (this.SocketErrorEvent != null)
                {
                    this.SocketErrorEvent("Error while start listen." + exception.Message);
                }
            }
        }

        private void method_1(Socket socket_1, int int_2)
        {
            try
            {
                if (this.asyncCallback_0 == null)
                {
                    this.asyncCallback_0 = new AsyncCallback(this.method_2);
                }
                if (socket_1.Connected)
                {
                    SocketPacket state = new SocketPacket(socket_1, int_2);
                    socket_1.BeginReceive(state.dataBuffer, 0, state.dataBuffer.Length, SocketFlags.None, this.asyncCallback_0, state);
                }
            }
            catch (SocketException exception)
            {
                if (this.SocketErrorEvent != null)
                {
                    this.SocketErrorEvent("Error while wait for data from client." + exception.Message);
                }
            }
        }

        private void method_2(IAsyncResult iasyncResult_0)
        {
            SocketPacket asyncState = (SocketPacket) iasyncResult_0.AsyncState;
            try
            {
                int dataReceivedLength = 0;
                dataReceivedLength = asyncState.clientSocket.EndReceive(iasyncResult_0);
                if (dataReceivedLength > 0)
                {
                    string dataReceivedString = Encoding.UTF8.GetString(asyncState.dataBuffer);
                    if (this.DataReceivedInStringEvent != null)
                    {
                        this.DataReceivedInStringEvent(dataReceivedString);
                    }
                    if (this.DataReceivedInByteArrayEvent != null)
                    {
                        this.DataReceivedInByteArrayEvent(asyncState.dataBuffer, dataReceivedLength);
                    }
                }
                this.method_1(asyncState.clientSocket, asyncState.clientNumber);
            }
            catch (ObjectDisposedException exception)
            {
                Debugger.Log(0, "1", "\nOnDataReceived: Socket has been closed\n");
                if (this.SocketErrorEvent != null)
                {
                    this.SocketErrorEvent("OnDataReceived: Socket has been closed.\n" + exception.Message);
                }
            }
            catch (SocketException exception2)
            {
                if (exception2.ErrorCode == 0x2746)
                {
                    string errorString = "\nClient " + asyncState.clientNumber + " Disconnected\n";
                    if (this.SocketErrorEvent != null)
                    {
                        this.SocketErrorEvent(errorString);
                    }
                    this.arrayList_0[asyncState.clientNumber - 1] = null;
                }
                else if (this.SocketErrorEvent != null)
                {
                    this.SocketErrorEvent("Error while get data received." + exception2.Message);
                }
            }
        }

        private void method_3()
        {
            this.bool_0 = false;
            if (this.socket_0 != null)
            {
                this.socket_0.Close();
            }
        }

        public void SaveFile(string receivedPath, byte[] clientData, int receivedBytesLen)
        {
            try
            {
                int count = BitConverter.ToInt32(clientData, 0);
                string str = Encoding.UTF8.GetString(clientData, 4, count);
                BinaryWriter writer = new BinaryWriter(System.IO.File.Open(receivedPath + "/" + str, FileMode.Append));
                writer.Write(clientData, 4 + count, (receivedBytesLen - 4) - count);
                writer.Close();
            }
            catch (Exception exception)
            {
                if (this.SocketErrorEvent != null)
                {
                    this.SocketErrorEvent("Error while saving file data." + exception.Message);
                }
            }
        }

        public void SendFile(string fileName)
        {
            try
            {
                string str = string.Empty;
                while (fileName.IndexOf(@"\") > -1)
                {
                    str = str + fileName.Substring(0, fileName.IndexOf(@"\") + 1);
                    fileName = fileName.Substring(fileName.IndexOf(@"\") + 1);
                }
                byte[] bytes = Encoding.UTF8.GetBytes(fileName);
                byte[] buffer2 = BitConverter.GetBytes(bytes.Length);
                byte[] buffer3 = System.IO.File.ReadAllBytes(str + fileName);
                byte[] array = new byte[(4 + bytes.Length) + buffer3.Length];
                buffer2.CopyTo(array, 0);
                bytes.CopyTo(array, 4);
                buffer3.CopyTo(array, (int) (4 + bytes.Length));
                this.SendMessage(array);
            }
            catch (Exception exception)
            {
                if (this.SocketErrorEvent != null)
                {
                    this.SocketErrorEvent("Error while sending file to client." + exception.Message);
                }
            }
        }

        public void SendMessage(byte[] message)
        {
            try
            {
                foreach (Socket socket in this.arrayList_0)
                {
                    if ((socket != null) && socket.Connected)
                    {
                        socket.Send(message);
                    }
                }
            }
            catch (SocketException exception)
            {
                if (this.SocketErrorEvent != null)
                {
                    this.SocketErrorEvent("Error while send message to client." + exception.Message);
                }
            }
        }

        public void SendMessage(string message)
        {
            try
            {
                byte[] bytes = Encoding.UTF8.GetBytes(message);
                foreach (Socket socket in this.arrayList_0)
                {
                    if ((socket != null) && socket.Connected)
                    {
                        socket.Send(bytes);
                    }
                }
            }
            catch (SocketException exception)
            {
                if (this.SocketErrorEvent != null)
                {
                    this.SocketErrorEvent("Error while send message to client." + exception.Message);
                }
            }
        }

        public void SendMessage(string message, int clientNumber)
        {
            try
            {
                byte[] bytes = Encoding.UTF8.GetBytes(message);
                int count = this.arrayList_0.Count;
                if (((count > 0) && (count > clientNumber)) && (clientNumber >= 0))
                {
                    ((Socket) this.arrayList_0[clientNumber]).Send(bytes);
                }
            }
            catch (SocketException exception)
            {
                if (this.SocketErrorEvent != null)
                {
                    this.SocketErrorEvent(string.Concat(new object[] { "Error while send message to client: ", clientNumber, "\n", exception.Message }));
                }
            }
        }

        public void SendMessage(byte[] message, int clientNumber)
        {
            try
            {
                int count = this.arrayList_0.Count;
                if (((count > 0) && (count > clientNumber)) && (clientNumber >= 0))
                {
                    Socket socket = (Socket) this.arrayList_0[clientNumber];
                    if ((socket != null) && socket.Connected)
                    {
                        socket.Send(message);
                    }
                }
            }
            catch (SocketException exception)
            {
                if (this.SocketErrorEvent != null)
                {
                    this.SocketErrorEvent(string.Concat(new object[] { "Error while send message to client: ", clientNumber, "\n", exception.Message }));
                }
            }
        }

        public void StartListen()
        {
            try
            {
                this.socket_0 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint localEP = new IPEndPoint(IPAddress.Any, this.int_1);
                this.socket_0.Bind(localEP);
                this.socket_0.Listen(4);
                this.socket_0.BeginAccept(new AsyncCallback(this.method_0), null);
                this.bool_0 = true;
            }
            catch (SocketException exception)
            {
                if (this.SocketErrorEvent != null)
                {
                    this.SocketErrorEvent(exception.Message);
                }
            }
        }

        public void StopListen()
        {
            this.method_3();
        }

        public int ClientCount
        {
            get
            {
                return this.int_0;
            }
        }

        public bool IsRunning
        {
            get
            {
                return this.bool_0;
            }
            set
            {
                this.bool_0 = value;
            }
        }

        public string ServerIP
        {
            get
            {
                return this.string_0;
            }
            set
            {
                this.string_0 = value;
            }
        }

        public int ServerPort
        {
            get
            {
                return this.int_1;
            }
            set
            {
                this.int_1 = value;
            }
        }
    }
}

